Post-Restart 502 While Docusaurus Is Building
This report documents the incident where brain.id86.net returned 502 Bad Gateway right after restarting the docusaurus container.
Issue Observed
- Site became unavailable after
sudo docker restart docusaurus. - Cloudflare Tunnel errors showed origin connection failure:
Unable to reach the origin service ... dial tcp 172.20.0.3:3000: connect: connection refused
docusauruscontainer was up, but the app was not serving yet.
Root Cause
The container startup command in the running container was:
sh -c "npm install --legacy-peer-deps && npm run build && npm run serve"
This creates a downtime window because:
npm installandnpm run buildrun first.- During that time, nothing listens on port
3000. - Cloudflare Tunnel forwards traffic immediately and receives
connection refused. - End users see
502untilnpm run servestarts.
What Was Checked
# container status
sudo docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# docusaurus runtime command
sudo docker inspect -f '{{.Config.Cmd}} | {{.Path}} {{.Args}}' docusaurus
# docusaurus logs
sudo docker logs --tail 120 docusaurus
# cloudflared logs
sudo docker logs --since 2m cloudflared
# running processes in docusaurus container
sudo docker exec docusaurus /bin/sh -lc "ps aux"
Recovery Applied
To restore service immediately, serve was started manually before the long build sequence completed:
sudo docker exec -d docusaurus /bin/sh -lc "npm run serve -- --host 0.0.0.0 --port 3000"
Verification Results
# origin responding
curl -s -o /dev/null -w "%{http_code}" http://172.20.0.3:3000
# expected: 200
# serve process running
sudo docker exec docusaurus /bin/sh -lc "ps aux | grep -E 'docusaurus (build|serve)' | grep -v grep"
Outcome:
- Origin returned
200. docusaurus serveprocess was confirmed running.- Site became reachable again through Cloudflare Access.
Preventive Actions
- Keep production startup aligned with
docker-compose.ymlso it does not block on long pre-serve steps. - If build/install must run, use a deployment flow that serves the previous build until the new build is ready.
- Add a healthcheck gate so tunnel traffic is sent only when origin is healthy.
- Keep this runbook command ready for emergency recovery:
sudo docker exec -d docusaurus /bin/sh -lc "npm run serve -- --host 0.0.0.0 --port 3000"